package com.maodou.core.network

import com.maodou.core.navigation.GlobalUiBus

fun defaultSuccessPredicate(code: String?, success: Boolean?): Boolean {
    if (success == true) return true
    val upper = code?.uppercase()
    return upper == "SUCCESS" || upper == "OK" || code == "0" || code == "200"
}

/**
 * 将 ApiEnvelope<T> 映射为 NetworkResult<T>，可注入自定义成功判定。
 */
fun <T> ApiEnvelope<T>.toResult(
    isSuccess: (code: String?, success: Boolean?) -> Boolean = ::defaultSuccessPredicate
): NetworkResult<T> {
    return if (isSuccess(code, success) && data != null) {
        NetworkResult.Success(data)
    } else {
        message?.let { GlobalUiBus.showError(it) }
        NetworkResult.Failure(NetworkError.Business(code = code, message = message))
    }
}

/**
 * 可选数据：即使 data == null 也按成功返回（适用于 data 为空但 success = true 的接口）。
 */
fun <T> ApiEnvelope<T?>.toOptionalResult(
    isSuccess: (code: String?, success: Boolean?) -> Boolean = ::defaultSuccessPredicate
): NetworkResult<T?> {
    return if (isSuccess(code, success)) {
        NetworkResult.Success(data)
    } else {
        message?.let { GlobalUiBus.showError(it) }
        NetworkResult.Failure(NetworkError.Business(code = code, message = message))
    }
}

/**
 * 无数据操作类接口：成功即返回 Unit。
 */
fun ApiEnvelope<*>.toUnitResult(
    isSuccess: (code: String?, success: Boolean?) -> Boolean = ::defaultSuccessPredicate
): NetworkResult<Unit> {
    return if (isSuccess(code, success)) {
        NetworkResult.Success(Unit)
    } else {
        message?.let { GlobalUiBus.showError(it) }
        NetworkResult.Failure(NetworkError.Business(code = code, message = message))
    }
}

/**
 * 泛化的映射：当成功时对 data 进行映射，否则返回 Failure。
 */
private inline fun <I, O> ApiEnvelope<I>.toMappedResult(
    crossinline mapper: (I) -> O,
    isSuccess: (code: String?, success: Boolean?) -> Boolean = ::defaultSuccessPredicate
): NetworkResult<O> {
    return if (isSuccess(code, success) && data != null) {
        NetworkResult.Success(mapper(data))
    } else {
        message?.let { GlobalUiBus.showError(it) }
        NetworkResult.Failure(NetworkError.Business(code = code, message = message))
    }
}

/**
 * 分页：保留完整分页信息。
 */
fun <T> ApiEnvelope<PageEnvelope<T>>.toPageResult(
    isSuccess: (code: String?, success: Boolean?) -> Boolean = ::defaultSuccessPredicate
): NetworkResult<PageEnvelope<T>> = toMappedResult(mapper = { it }, isSuccess)

/**
 * 分页：仅提取 records 作为最终列表数据。
 */
fun <T> ApiEnvelope<PageEnvelope<T>>.toRecordsResult(
    isSuccess: (code: String?, success: Boolean?) -> Boolean = ::defaultSuccessPredicate
): NetworkResult<List<T>> = toMappedResult(mapper = { it.records }, isSuccess)